
// INCLUDES ********************************************************************

#include "Texture2D.h"

#include "TextureCache.h"

#include "Logger.h"

#include "TouchController.h"

#include "Button.h"

#include "Function.h"


// NAMESPACES ******************************************************************

using namespace Meteor;


#pragma mark -
#pragma mark Constructors/Destructor
// -----------------------------------------------------------------------------

Meteor::Button::Button( const std::string& normalImage, 
                        const std::string& altImage)

: Sprite( normalImage), TouchListener(), mTextureOrignal( nullptr), mCallback( nullptr)
{
    mTextureAlt = TextureCache::Instance().AddObject( altImage);
    
    TouchController::Instance().AddTouchListener( this);
    
    mTextureOrignal = mTexture;
}

// -----------------------------------------------------------------------------

Meteor::Button::Button( const std::string& normalImage, 
                        const std::string& altImage,
                        const uint32_t zIndex)

: Sprite( normalImage, zIndex), TouchListener(), mTextureOrignal( nullptr),
  mCallback( nullptr)
{    
    mTextureAlt = TextureCache::Instance().AddObject( altImage);
    
    TouchController::Instance().AddTouchListener( this);
    
    mTextureOrignal = mTexture;
}

// -----------------------------------------------------------------------------

Meteor::Button::~Button()
{
    TextureCache::Instance().RemoveObject( mTextureAlt->Filename());
    
    TouchController::Instance().RemoveTouchListener( this);
}


#pragma mark -
#pragma mark Touch handling
// -----------------------------------------------------------------------------

void Meteor::Button::TouchBegan( const Vector2D& position)
{    
    Rectangle imageRect( mPosition.X() - ( mSize.X() * mAnchorPoint.X()), 
                         mPosition.Y() - ( mSize.Y() * mAnchorPoint.Y()),
                         mSize.X(),
                         mSize.Y());

    if ( imageRect.Contains( position))
    { 
        if ( mTextureAlt != nullptr)
        {    
            mTexture = mTextureAlt;
        }
        
        mDidSwallowTouch = true && mSwallowsTouches;
    }
    else
    {
        mDidSwallowTouch = false;
    }
}

// -----------------------------------------------------------------------------

void Meteor::Button::TouchMoved( const Vector2D& position)
{
    if ( mTextureOrignal != nullptr)
    {
        mTexture = mTextureOrignal;
    }
    
    Rectangle imageRect( mPosition.X() - ( mSize.X() * mAnchorPoint.X()), 
                         mPosition.Y() - ( mSize.Y() * mAnchorPoint.Y()),
                         mSize.X(),
                         mSize.Y());
    
    if ( imageRect.Contains( position))
    {
        mDidSwallowTouch = true && mSwallowsTouches;
    }
    else
    {
        mDidSwallowTouch = false;
    }
}

// -----------------------------------------------------------------------------

void Meteor::Button::TouchEnded( const Vector2D& position, double duration)
{
    Rectangle imageRect( mPosition.X() - ( mSize.X() * mAnchorPoint.X()), 
                         mPosition.Y() - ( mSize.Y() * mAnchorPoint.Y()),
                         mSize.X(),
                         mSize.Y());
    
    if ( imageRect.Contains( position) == true)
    {
        if ( mTextureOrignal != nullptr)
        {
            mTexture = mTextureOrignal;
        }
        
        mDidSwallowTouch = true && mSwallowsTouches;

        if ( mCallback != nullptr)
        {
            ( *mCallback)();
        }
    }
    else
    {
        mDidSwallowTouch = false;
    }
}

#pragma mark -
#pragma mark Callback
// -----------------------------------------------------------------------------

void Meteor::Button::SetCallback( Function* callback)
{
    mCallback = callback;
}

